前一篇已經提前預告接下來將會講繼承了,所以這一篇當然就是會介紹繼承啦~(廢話)
繼承是什麼呢?JavaScript 有嗎?JavaScript 是有的哦。
那麼簡單來講繼承的概念,假設是用人的角度來形容的話,你可以把它想像成有一個爸爸,然後他會有一個兒子(廢話),然後這個兒子會有爸爸的一些生物特徵,例如:可以爸爸眼睛瞳孔顏色是藍色的,所以兒子繼承下來的瞳孔顏色也就會是藍色的。
所以前面我們就簡單寫一個 JavaScript 的繼承版本稍微參考一下:
function Father(pupil) {
this.pupil = pupil || '藍色'; // 瞳孔顏色
}
function Son(name) {
Father.call(this);
this.name = name; // 兒子的名字
}
Son.prototype = Object.create(Father.prototype);
Son.prototype.constructor = Son;
Son.prototype.eyeColor = function() {
console.log(this.name + ' 眼睛顏色是:' + this.pupil);
}
const ray = new Son('Ray');
ray.eyeColor(); // Ray 眼睛顏色是:藍色
透過上面簡單的範例,我們可以看到不管怎樣,兒子的眼睛顏色會是繼承來自爸爸的瞳孔顏色,而這就是一個非常簡單的繼承概念,如果你對於上面的程式碼不是那麼熟悉的話,我會建議你可以先閱讀我先前寫的筆記 繼承與原型鍊 的部分,因此這邊就不多著墨於這一塊,接下來就直接準備進入了解 Python 的繼承是如何撰寫囉~
但是這邊也可以簡單寫一次 JavaScript 的 ES6 class
版本的寫法:
class Father {
constructor(pupil) {
this.pupil = pupil || '藍色'; // 瞳孔顏色
}
}
class Son extends Father {
constructor(name) {
super()
this.name = name; // 兒子的名字
}
eyeColor() {
console.log(this.name + ' 眼睛顏色是:' + this.pupil);
}
}
const ray = new Son('Ray');
ray.eyeColor(); // Ray 眼睛顏色是:藍色
基本上你會看到 prototype
的寫法跟 class
的寫法有很明顯的不同,在語法上的撰寫也相對簡易很多,可是這邊要注意 JavaScript 依然是以原型為導向的語言,class
只是一個語法糖而已,在底層實作上依然是 prototype
的概念。
前面稍微回顧了 JavaScript 的繼承概念與寫法之後,接下來當然是拉回到 Python 中啦~
那 Python 中的繼承寫法會非常複雜嗎?其實並不會,這邊讓我們換一個練習範本,我們先用前面 JavaScript 的範本建立一個 class 出來:
class Father:
def __init__(self, pupil):
self.pupil = pupil or '藍色'
好,那接下來繼承該如何寫呢?
不,絕對不是使用 extends
語法。
Python 的繼承語法非常簡潔,只需要在 class
名稱後方加上括號並傳入要繼承的 class
名稱就可以了:
class Father:
def __init__(self, pupil):
self.pupil = pupil or '藍色'
class Son(Father):
pass
有沒有發現非常簡單呢?如果你不知道我寫 pass
的用途的話,建議你可以往前一篇看這邊就不解釋了。
那麼接下來讓我們直接補完 Son
的內容再繼續往下介紹:
class Father:
def __init__(self, pupil):
self.pupil = pupil or '藍色'
class Son(Father):
def __init__(self, name):
self.name = name
def eyeColor(self):
print(this.name + ' 眼睛顏色是:' + this.pupil)
這時候不用急著實例化 Son
,基本上這一段是會出現一段錯誤訊息,也就是「AttributeError: 'Son' object has no attribute 'pupil'
」的錯誤訊息,主要原因是因為當我們在子類別中使用 __init__
方法時,是會覆蓋原有父類別的繼承 __init__
,所以這邊我們必須重新將 Father
重新繼承回來,而重新繼承寫法其實有兩種,第一種就是是使用 __init__
:
class Father:
def __init__(self, pupil):
self.pupil = pupil or '藍色'
class Son(Father):
def __init__(self, name):
Father.__init__(self, '')
self.name = name
def eyeColor(self):
print(self.name + ' 眼睛顏色是:' + self.pupil)
ray = Son('Ray')
ray.eyeColor() # Ray 眼睛顏色是:藍色
這樣子上面這一段範例程式碼,就可正常的運作囉~
那另一種方式則是使用 super
的函式重新繼承:
class Father:
def __init__(self, pupil):
self.pupil = pupil or '藍色'
class Son(Father):
def __init__(self, name):
super().__init__('')
self.name = name
def eyeColor(self):
print(self.name + ' 眼睛顏色是:' + self.pupil)
ray = Son('Ray')
ray.eyeColor() # Ray 眼睛顏色是:藍色
使用 super
函式的好處在於,你不用去撰寫父類別的名稱,它會自動去尋找你所傳入的副類別名稱,然後自動重新繼承父類別的屬性與函式。
那你看到這邊之後有沒有覺得 Python 與 JavaScript 的 class
是不是有相似之處呢?
那這一篇也算是到這邊結束了,主要是補完前一章節關於 class
的部分。
因為工作的關係,自己時常很忙比較少在打掃家中,所以很仰賴小瓦機器人掃跟拖地,但是最近在幫小瓦機器人清理集塵盒的時候...
不小心把集塵盒捏爆了...囧